

package com.geek.bams.client;

import com.geek.bams.entity.Account;
import com.geek.bams.entity.CreditAccount;
import com.geek.bams.entity.LoanSavingAccount;
import com.geek.bams.entity.LoanCreditAccount;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class BusinessPanel extends JPanel {

    private ATMClient atm;

    public BusinessPanel(ATMClient atm) {
        this.atm = atm;
        initComponents();
        
        // 设置刷新监听器，当收到服务器推送的刷新通知时自动刷新
        atm.clientService.setRefreshListener(new ClientService.RefreshListener() {
            @Override
            public void onRefreshNeeded() {
                // 在EDT线程中刷新账户信息
                SwingUtilities.invokeLater(() -> {
                    refreshAccountInfoFromServer();
                });
            }
            
            @Override
            public void onForceLogout(String message) {
                // 强制登出
                SwingUtilities.invokeLater(() -> {
                    JOptionPane.showMessageDialog(BusinessPanel.this, 
                        message, 
                        "账户已在其他地方登录", 
                        JOptionPane.WARNING_MESSAGE);
                    // 执行登出操作
                    back(null);
                });
            }
            
            @Override
            public void onServerShutdown() {
                // 服务器关闭
                SwingUtilities.invokeLater(() -> {
                    JOptionPane.showMessageDialog(BusinessPanel.this, 
                        "服务器已关闭，无法继续操作！\n请重新启动服务器后再试。", 
                        "服务器关闭", 
                        JOptionPane.ERROR_MESSAGE);
                    // 执行登出操作
                    back(null);
                });
            }
        });
        
        // 添加组件监听器，当面板变为可见时刷新账户信息
        this.addComponentListener(new java.awt.event.ComponentAdapter() {
            @Override
            public void componentShown(java.awt.event.ComponentEvent e) {
                refreshAccountInfo();
            }
        });
    }
    
    /**
     * 从服务器获取最新账户信息并刷新显示
     */
    private void refreshAccountInfoFromServer() {
        if (atm.acc == null || atm.currentPassword == null) {
            return;
        }
        
        // 从服务器获取最新账户信息
        Object result = atm.clientService.getAccount(atm.acc.getId(), atm.currentPassword);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount;
            refreshAccountInfo();
            
            // 可选：显示通知提示
            JOptionPane.showMessageDialog(this, 
                "账户信息已更新！\n当前余额：" + String.format("%.2f", updatedAccount.getBalance()) + "元", 
                "账户更新", 
                JOptionPane.INFORMATION_MESSAGE);
        }
    }

    // 刷新账户信息显示
    private void refreshAccountInfo() {
        if (atm.acc != null) {
            label9.setText(String.valueOf(atm.acc.getId())); // 账户ID
            label10.setText(atm.acc.getName()); // 姓名
            label8.setText(String.format("%.2f", atm.acc.getBalance())); // 余额
            
            // 显示信用额度（仅信用账户）
            if (atm.acc instanceof CreditAccount) {
                CreditAccount creditAccount = (CreditAccount) atm.acc;
                label11.setText(String.format("%.2f", creditAccount.getCeiling()));
            } else {
                label11.setText("不适用");
            }
            
            // 显示贷款额（仅可贷款账户）
            if (atm.acc instanceof LoanSavingAccount) {
                LoanSavingAccount loanAccount = (LoanSavingAccount) atm.acc;
                label12.setText(String.format("%.2f", (double)loanAccount.getLoanAmount()));
            } else if (atm.acc instanceof LoanCreditAccount) {
                LoanCreditAccount loanAccount = (LoanCreditAccount) atm.acc;
                label12.setText(String.format("%.2f", (double)loanAccount.getLoanAmount()));
            } else {
                label12.setText("不适用");
            }
        }
    }
    
    // 处理业务操作
    private void submit(ActionEvent e) {
        if (atm.acc == null) {
            JOptionPane.showMessageDialog(this, "请先登录！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        // 检查服务器连接状态
        if (!atm.clientService.isConnected()) {
            JOptionPane.showMessageDialog(this, 
                "服务器连接已断开，无法执行操作！\n请重新启动服务器后再试。", 
                "连接错误", 
                JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        String operation = (String) comboBox1.getSelectedItem();
        String amountStr = textField1.getText().trim();
        
        if (amountStr.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入金额！", "输入错误", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        try {
            double amount = Double.parseDouble(amountStr);
            
            if (amount <= 0) {
                JOptionPane.showMessageDialog(this, "金额必须大于0！", "输入错误", JOptionPane.WARNING_MESSAGE);
                return;
            }
            
            switch (operation) {
                case "存款":
                    handleDeposit(amount);
                    break;
                case "取款":
                    handleWithdraw(amount);
                    break;
                case "转账":
                    handleTransfer(amount);
                    break;
                case "贷款":
                    handleLoan(amount);
                    break;
                case "设置透支额度":
                    handleSetCeiling(amount);
                    break;
                case "还款":
                    handleRepayment(amount);
                    break;
                default:
                    JOptionPane.showMessageDialog(this, "未知操作！", "错误", JOptionPane.ERROR_MESSAGE);
            }
            
            // 清空输入框并刷新账户信息
            textField1.setText("");
            refreshAccountInfo();
            
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "请输入有效的数字！", "输入错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 存款操作
    private void handleDeposit(double amount) {
        Object result = atm.clientService.deposit(atm.acc.getId(), amount);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount; // 更新本地账户信息
            JOptionPane.showMessageDialog(this, 
                String.format("存款成功！存入金额：%.2f元\n当前余额：%.2f元", amount, updatedAccount.getBalance()), 
                "操作成功", JOptionPane.INFORMATION_MESSAGE);
        } else if (result instanceof String) {
            JOptionPane.showMessageDialog(this, "存款失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 取款操作
    private void handleWithdraw(double amount) {
        Object result = atm.clientService.withdraw(atm.acc.getId(), atm.currentPassword, amount);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount; // 更新本地账户信息
            JOptionPane.showMessageDialog(this, 
                String.format("取款成功！取出金额：%.2f元\n当前余额：%.2f元", amount, updatedAccount.getBalance()), 
                "操作成功", JOptionPane.INFORMATION_MESSAGE);
        } else if (result instanceof String) {
            JOptionPane.showMessageDialog(this, "取款失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 转账操作
    private void handleTransfer(double amount) {
        // 获取目标账户ID
        String targetIdStr = JOptionPane.showInputDialog(this, 
            "请输入目标账户ID：", 
            "转账", 
            JOptionPane.QUESTION_MESSAGE);
        
        if (targetIdStr == null || targetIdStr.trim().isEmpty()) {
            return; // 用户取消或未输入
        }
        
        try {
            Long targetId = Long.parseLong(targetIdStr.trim());
            
            // 检查是否转账给自己
            if (targetId.equals(atm.acc.getId())) {
                JOptionPane.showMessageDialog(this, "不能转账给自己！", "转账失败", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
            Object result = atm.clientService.transfer(atm.acc.getId(), atm.currentPassword, targetId, amount);
            if (result instanceof Account) {
                // 转账成功，更新账户信息
                Account updatedAccount = (Account) result;
                atm.acc = updatedAccount;
                JOptionPane.showMessageDialog(this, 
                    String.format("转账成功！\n转账金额：%.2f元\n目标账户：%d\n当前余额：%.2f元", 
                        amount, targetId, updatedAccount.getBalance()), 
                    "操作成功", JOptionPane.INFORMATION_MESSAGE);
            } else if (result instanceof String) {
                JOptionPane.showMessageDialog(this, "转账失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "目标账户ID格式错误，请输入数字！", "输入错误", JOptionPane.ERROR_MESSAGE);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, "转账失败：" + ex.getMessage(), "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 贷款操作
    private void handleLoan(double amount) {
        if (!(atm.acc instanceof LoanSavingAccount) && !(atm.acc instanceof LoanCreditAccount)) {
            JOptionPane.showMessageDialog(this, "您的账户不支持贷款功能！", "操作失败", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        Object result = atm.clientService.requestLoan(atm.acc.getId(), amount);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount;
            JOptionPane.showMessageDialog(this, 
                String.format("贷款成功！贷款金额：%.2f元\n当前余额：%.2f元", amount, updatedAccount.getBalance()), 
                "操作成功", JOptionPane.INFORMATION_MESSAGE);
        } else if (result instanceof String) {
            JOptionPane.showMessageDialog(this, "贷款失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 设置透支额度
    private void handleSetCeiling(double ceiling) {
        if (!(atm.acc instanceof CreditAccount)) {
            JOptionPane.showMessageDialog(this, "您的账户不支持设置透支额度！", "操作失败", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        Object result = atm.clientService.updateCeiling(atm.acc.getId(), atm.currentPassword, ceiling);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount;
            JOptionPane.showMessageDialog(this, 
                String.format("透支额度设置成功！新额度：%.2f元", ceiling), 
                "操作成功", JOptionPane.INFORMATION_MESSAGE);
        } else if (result instanceof String) {
            JOptionPane.showMessageDialog(this, "设置透支额度失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // 还款操作
    private void handleRepayment(double amount) {
        if (!(atm.acc instanceof LoanSavingAccount) && !(atm.acc instanceof LoanCreditAccount)) {
            JOptionPane.showMessageDialog(this, "您的账户不支持还款功能！", "操作失败", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        Object result = atm.clientService.payLoan(atm.acc.getId(), amount);
        if (result instanceof Account) {
            Account updatedAccount = (Account) result;
            atm.acc = updatedAccount;
            JOptionPane.showMessageDialog(this, 
                String.format("还款成功！还款金额：%.2f元\n剩余贷款：%.2f元", amount, 
                    updatedAccount instanceof LoanSavingAccount ? 
                        (double)((LoanSavingAccount)updatedAccount).getLoanAmount() : 
                        (double)((LoanCreditAccount)updatedAccount).getLoanAmount()), 
                "操作成功", JOptionPane.INFORMATION_MESSAGE);
        } else if (result instanceof String) {
            JOptionPane.showMessageDialog(this, "还款失败：" + result, "操作失败", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void confirm(ActionEvent e) {
        // 这个方法似乎在UI中没有使用，保持为空或者可以用作其他功能
        CardLayout cardLayout = (CardLayout)this.getParent().getLayout();
        cardLayout.show(this.getParent(), "businessPanel");
    }

    private void back(ActionEvent e) {
        // 退出登录，清空账户信息和密码
        atm.acc = null;
        atm.currentPassword = null;
        
        // 清空输入框
        textField1.setText("");
        
        // 返回主界面
        CardLayout cardLayout = (CardLayout)this.getParent().getLayout();
        cardLayout.show(this.getParent(), "mainPanel");
        
        JOptionPane.showMessageDialog(this, "已安全退出登录！", "退出成功", JOptionPane.INFORMATION_MESSAGE);
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents  @formatter:off
        comboBox1 = new JComboBox<>();
        textField1 = new JTextField();
        submitButton = new JButton();
        label1 = new JLabel();
        label2 = new JLabel();
        label3 = new JLabel();
        label6 = new JLabel();
        label7 = new JLabel();
        backButton = new JButton();
        label8 = new JLabel();
        label9 = new JLabel();
        label10 = new JLabel();
        label11 = new JLabel();
        label12 = new JLabel();
        this2 = new JPanel();
        confirmButton2 = new JButton();
        cancelButton2 = new JButton();
        label4 = new JLabel();
        nameTextField2 = new JTextField();
        passwordField2 = new JPasswordField();
        label5 = new JLabel();

        //======== this ========
        setLayout(null);

        //---- comboBox1 ----
        comboBox1.setModel(new DefaultComboBoxModel<>(new String[] {
                "\u5b58\u6b3e",
                "\u53d6\u6b3e",
                "\u8f6c\u8d26",
                "\u8d37\u6b3e",
                "\u8bbe\u7f6e\u900f\u652f\u989d\u5ea6",
                "\u8fd8\u6b3e"
        }));
        add(comboBox1);
        comboBox1.setBounds(125, 390, 100, 35);
        add(textField1);
        textField1.setBounds(250, 390, 100, 35);

        //---- submitButton ----
        submitButton.setText("\u63d0\u4ea4");
        submitButton.addActionListener(e -> submit(e));
        add(submitButton);
        submitButton.setBounds(130, 455, 85, 35);

        //---- label1 ----
        label1.setText(" \u8d26     \u6237\uff1a");
        label1.setHorizontalAlignment(SwingConstants.CENTER);
        add(label1);
        label1.setBounds(115, 115, 115, 40);

        //---- label2 ----
        label2.setText(" \u59d3     \u540d\uff1a");
        label2.setHorizontalAlignment(SwingConstants.CENTER);
        add(label2);
        label2.setBounds(115, 160, 115, 40);

        //---- label3 ----
        label3.setText("\u4f59     \u989d\uff1a");
        label3.setHorizontalAlignment(SwingConstants.CENTER);
        add(label3);
        label3.setBounds(115, 205, 115, 40);

        //---- label6 ----
        label6.setText("\u4fe1\u7528\u989d\u5ea6\uff1a");
        label6.setHorizontalAlignment(SwingConstants.CENTER);
        add(label6);
        label6.setBounds(115, 250, 115, 40);

        //---- label7 ----
        label7.setText("\u8d37  \u6b3e  \u989d\uff1a");
        label7.setHorizontalAlignment(SwingConstants.CENTER);
        add(label7);
        label7.setBounds(115, 305, 115, 40);

        //---- backButton ----
        backButton.setText("\u8fd4\u56de");
        backButton.addActionListener(e -> back(e));
        add(backButton);
        backButton.setBounds(265, 455, 85, 35);

        //---- label8 ----
        label8.setHorizontalAlignment(SwingConstants.CENTER);
        add(label8);
        label8.setBounds(245, 205, 115, 40);

        //---- label9 ----
        label9.setHorizontalAlignment(SwingConstants.CENTER);
        add(label9);
        label9.setBounds(245, 115, 115, 40);

        //---- label10 ----
        label10.setHorizontalAlignment(SwingConstants.CENTER);
        add(label10);
        label10.setBounds(245, 160, 115, 40);

        //---- label11 ----
        label11.setHorizontalAlignment(SwingConstants.CENTER);
        add(label11);
        label11.setBounds(245, 250, 115, 40);

        //---- label12 ----
        label12.setHorizontalAlignment(SwingConstants.CENTER);
        add(label12);
        label12.setBounds(245, 305, 115, 40);

        setPreferredSize(new Dimension(500, 650));

        //======== this2 ========
        {
            this2.setLayout(null);

            //---- confirmButton2 ----
            confirmButton2.setText("\u786e\u8ba4");
            confirmButton2.addActionListener(e -> {
                submit(e);
                confirm(e);
            });
            this2.add(confirmButton2);
            confirmButton2.setBounds(120, 390, 78, 34);

            //---- cancelButton2 ----
            cancelButton2.setText("\u53d6\u6d88");
            cancelButton2.addActionListener(e -> submit(e));
            this2.add(cancelButton2);
            cancelButton2.setBounds(305, 390, 78, 34);

            //---- label4 ----
            label4.setText("\u7528\u6237\u8d26\u53f7");
            label4.setHorizontalAlignment(SwingConstants.CENTER);
            this2.add(label4);
            label4.setBounds(100, 235, 115, 40);
            this2.add(nameTextField2);
            nameTextField2.setBounds(220, 235, 155, 40);
            this2.add(passwordField2);
            passwordField2.setBounds(220, 285, 155, 40);

            //---- label5 ----
            label5.setText("\u7528\u6237\u5bc6\u7801");
            label5.setHorizontalAlignment(SwingConstants.CENTER);
            this2.add(label5);
            label5.setBounds(100, 285, 115, 40);

            this2.setPreferredSize(new Dimension(500, 650));
        }
        // JFormDesigner - End of component initialization  //GEN-END:initComponents  @formatter:on
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables  @formatter:off
    private JComboBox<String> comboBox1;
    private JTextField textField1;
    private JButton submitButton;
    private JLabel label1;
    private JLabel label2;
    private JLabel label3;
    private JLabel label6;
    private JLabel label7;
    private JButton backButton;
    private JLabel label8;
    private JLabel label9;
    private JLabel label10;
    private JLabel label11;
    private JLabel label12;
    private JPanel this2;
    private JButton confirmButton2;
    private JButton cancelButton2;
    private JLabel label4;
    private JTextField nameTextField2;
    private JPasswordField passwordField2;
    private JLabel label5;
    // JFormDesigner - End of variables declaration  //GEN-END:variables  @formatter:on
}
